package aip.assignment2.view.customer;

import aip.assignment2.persistence.entity.Address;
import aip.assignment2.persistence.entity.Country;
import aip.assignment2.persistence.entity.CreditCard;
import aip.assignment2.persistence.entity.CreditCardType;
import aip.assignment2.persistence.entity.Customer;
import aip.assignment2.persistence.entity.PersonName;
import aip.assignment2.persistence.entity.PersonTitle;
import aip.assignment2.persistence.entity.Purchase;
import aip.assignment2.service.Application;
import aip.assignment2.service.PurchaseManager;
import aip.assignment2.service.entity.ProductInCart;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.logging.Level;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

/**
 * This class is the backing bean of "checkout.xhtml".
 */
@ManagedBean(name = "checkOut")
@SessionScoped
public class CheckOut implements Serializable
{
	@EJB
	private PurchaseManager m_PurchaseManager;
	@EJB
	private Application m_Application;
	// <editor-fold desc="Property - personTitles - Get" defaultstate="collapsed">
	public List<PersonTitle> getPersonTitles()
	{
		return m_PurchaseManager.getPersonTitles();
	}
	// </editor-fold>
	// <editor-fold desc="Property - countries - Get" defaultstate="collapsed">
	public List<Country> getCountries()
	{
		return m_PurchaseManager.getCountries();
	}
	// </editor-fold>
	// <editor-fold desc="Property - creditCardTypes - Get" defaultstate="collapsed">
	public List<CreditCardType> getCreditCardTypes()
	{
		return m_PurchaseManager.getCreditCardTypes();
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentPersonTitle - Get" defaultstate="collapsed">
	/**
	 * the current person title
	 */
	private PersonTitle currentPersonTitle;
	/**
	 * Gets the current person title.
	 */
	public PersonTitle getCurrentPersonTitle()
	{
		if (currentPersonTitle == null && !m_PurchaseManager.getPersonTitles().isEmpty())
		{
			currentPersonTitle = m_PurchaseManager.getPersonTitles().get(0);
		}
		return currentPersonTitle;
	}
	/**
	 * Sets the current person title.
	 */
	public void setCurrentPersonTitle(PersonTitle currentPersonTitle)
	{
		this.currentPersonTitle = currentPersonTitle;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentSurname - Get/Set" defaultstate="collapsed">
	/**
	 * the current surname
	 */
	private String currentSurname;
	/**
	 * Gets the current surname
	 */
	public String getCurrentSurname()
	{
		return currentSurname;
	}
	/**
	 * Sets the current surname
	 */
	public void setCurrentSurname(String currentSurname)
	{
		this.currentSurname = currentSurname;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentGivenName - Get/Set" defaultstate="collapsed">
	/**
	 * the current given name
	 */
	private String currentGivenName;
	/**
	 * Gets the current given name
	 */
	public String getCurrentGivenName()
	{
		return currentGivenName;
	}
	/**
	 * Sets the current given name
	 */
	public void setCurrentGivenName(String currentGivenName)
	{
		this.currentGivenName = currentGivenName;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentFullName - Get" defaultstate="collapsed">
	/**
	 * Gets the current full name.
	 */
	public String getCurrentFullName()
	{
		if (currentPersonTitle == null || currentSurname == null || currentGivenName == null)
		{
			return null;
		}
		return currentPersonTitle.getName() + " " + currentGivenName + " " + currentSurname;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentEmail - Get/Set" defaultstate="collapsed">
	/**
	 * the current email
	 */
	private String currentEmail;
	/**
	 * Gets the current email
	 */
	public String getCurrentEmail()
	{
		return currentEmail;
	}
	/**
	 * Sets the current email
	 */
	public void setCurrentEmail(String currentEmail)
	{
		this.currentEmail = currentEmail;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentNumber - Get/Set" defaultstate="collapsed">
	/**
	 * the current number
	 */
	private String currentNumber;
	/**
	 * Gets the current number
	 */
	public String getCurrentNumber()
	{
		return currentNumber;
	}
	/**
	 * Sets the current number
	 */
	public void setCurrentNumber(String currentNumber)
	{
		this.currentNumber = currentNumber;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentStreet - Get/Set" defaultstate="collapsed">
	/**
	 * the current street
	 */
	private String currentStreet;
	/**
	 * Gets the current street
	 */
	public String getCurrentStreet()
	{
		return currentStreet;
	}
	/**
	 * Sets the current street
	 */
	public void setCurrentStreet(String currentStreet)
	{
		this.currentStreet = currentStreet;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentState - Get/Set" defaultstate="collapsed">
	/**
	 * the current state
	 */
	private String currentState;
	/**
	 * Gets the current state
	 */
	public String getCurrentState()
	{
		return currentState;
	}
	/**
	 * Sets the current state
	 */
	public void setCurrentState(String currentState)
	{
		this.currentState = currentState;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentSuburb - Get/Set" defaultstate="collapsed">
	/**
	 * the current suburb
	 */
	private String currentSuburb;
	/**
	 * Gets the current suburb
	 */
	public String getCurrentSuburb()
	{
		return currentSuburb;
	}
	/**
	 * Sets the current suburb
	 */
	public void setCurrentSuburb(String currentSuburb)
	{
		this.currentSuburb = currentSuburb;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentPostcode - Get/Set" defaultstate="collapsed">
	/**
	 * the current postcode
	 */
	private String currentPostcode;
	/**
	 * Gets the current postcode
	 */
	public String getCurrentPostcode()
	{
		return currentPostcode;
	}
	/**
	 * Sets the current postcode
	 */
	public void setCurrentPostcode(String currentPostcode)
	{
		this.currentPostcode = currentPostcode;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentCountry - Get/Set" defaultstate="collapsed">
	/**
	 * the current country
	 */
	private Country currentCountry;
	/**
	 * Gets the current country
	 */
	public Country getCurrentCountry()
	{
		if (currentCountry == null && !m_PurchaseManager.getCountries().isEmpty())
		{
			currentCountry = m_PurchaseManager.getCountries().get(0);
		}
		return currentCountry;
	}
	/**
	 * Sets the current country
	 */
	public void setCurrentCountry(Country currentCountry)
	{
		this.currentCountry = currentCountry;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentFullAddress - Get" defaultstate="collapsed">
	/**
	 * Gets the current full address.
	 */
	public String getCurrentFullAddress()
	{
		if (currentNumber == null || currentStreet == null || currentState == null || currentSuburb == null || currentPostcode == null || currentCountry == null)
		{
			return null;
		}
		return currentNumber + ", " + currentStreet + ", " + currentSuburb + ", " + currentState + ", " + currentPostcode + ", " + currentCountry.getName();
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentCreditCardType - Get/Set" defaultstate="collapsed">
	/**
	 * the current credit card type
	 */
	private CreditCardType currentCreditCardType;
	/**
	 * Gets the current credit card type.
	 */
	public CreditCardType getCurrentCreditCardType()
	{
		if (currentCreditCardType == null && !m_PurchaseManager.getCreditCardTypes().isEmpty())
		{
			currentCreditCardType = m_PurchaseManager.getCreditCardTypes().get(0);
		}
		return currentCreditCardType;
	}
	/**
	 * Sets the current credit card type.
	 */
	public void setCurrentCreditCardType(CreditCardType currentCreditCardType)
	{
		this.currentCreditCardType = currentCreditCardType;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentCreditCardNumber - Get/Set" defaultstate="collapsed">
	/**
	 * the current credit card number
	 */
	private String currentCreditCardNumber;
	/**
	 * Gets the current credit card number.
	 */
	public String getCurrentCreditCardNumber()
	{
		return currentCreditCardNumber;
	}
	/**
	 * Sets the current credit card number.
	 */
	public void setCurrentCreditCardNumber(String currentCreditCardNumber)
	{
		this.currentCreditCardNumber = currentCreditCardNumber;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentCreditCardSecurityCode - Get/Set" defaultstate="collapsed">
	/**
	 * the current credit card security code
	 */
	private String currentCreditCardSecurityCode;
	/**
	 * Gets the current credit card security code.
	 */
	public String getCurrentCreditCardSecurityCode()
	{
		return currentCreditCardSecurityCode;
	}
	/**
	 * Sets the current credit card security code.
	 */
	public void setCurrentCreditCardSecurityCode(String currentCreditCardSecurityCode)
	{
		this.currentCreditCardSecurityCode = currentCreditCardSecurityCode;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentCreditCardExpiryYear - Get/Set" defaultstate="collapsed">
	/**
	 * the current credit card expiry year
	 */
	private int currentCreditCardExpiryYear;
	/**
	 * Gets the current credit card expiry year.
	 */
	public int getCurrentCreditCardExpiryYear()
	{
		return currentCreditCardExpiryYear;
	}
	/**
	 * Sets the current credit card expiry year.
	 */
	public void setCurrentCreditCardExpiryYear(int currentCreditCardExpiryYear)
	{
		this.currentCreditCardExpiryYear = currentCreditCardExpiryYear;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentCreditCardExpiryMonth - Get/Set" defaultstate="collapsed">
	/**
	 * the current credit card expiry month
	 */
	private int currentCreditCardExpiryMonth;
	/**
	 * Gets the current credit card expiry month.
	 */
	public int getCurrentCreditCardExpiryMonth()
	{
		return currentCreditCardExpiryMonth;
	}
	/**
	 * Sets the current credit card expiry month.
	 */
	public void setCurrentCreditCardExpiryMonth(int currentCreditCardExpiryMonth)
	{
		this.currentCreditCardExpiryMonth = currentCreditCardExpiryMonth;
	}
	// </editor-fold>
	// <editor-fold desc="Property - currentFullCreditCard - Get" defaultstate="collapsed">
	/**
	 * Gets the current full credit card.
	 */
	public String getCurrentFullCreditCard()
	{
		if (currentCreditCardType == null || currentCreditCardNumber == null || currentCreditCardSecurityCode == null || currentCreditCardExpiryMonth < 1 || currentCreditCardExpiryYear < 1)
		{
			return null;
		}
		return currentCreditCardType.getName() + " " + currentCreditCardNumber + " " + currentCreditCardSecurityCode + " " + currentCreditCardExpiryMonth + "/" + currentCreditCardExpiryYear;
	}
	// </editor-fold>
	// <editor-fold desc="Property - newPurchase - Get/Set" defaultstate="collapsed">
	/**
	 * the new purchase
	 */
	private Purchase newPurchase;
	/**
	 * Gets new purchase
	 */
	public Purchase getNewPurchase()
	{
		return newPurchase;
	}
	/**
	 * Sets new purchase
	 */
	public void setNewPurchase(Purchase newPurchase)
	{
		this.newPurchase = newPurchase;
	}
	// </editor-fold>
	/**
	 * This method creates a new purchase using the current customer information. Besides, it will also terminate the current session.
	 * @return
	 */
	public void create(List<ProductInCart> productsInCart)
	{
		if (productsInCart == null || productsInCart.isEmpty() || getCurrentFullName() == null || getCurrentEmail() == null || getCurrentFullAddress() == null || getCurrentFullCreditCard() == null)
		{
			m_Application.addMessage(FacesMessage.SEVERITY_FATAL, "Incomplete parameters are found.");
			return;
		}
		PersonName personName = new PersonName();
		personName.setTitle(currentPersonTitle);
		personName.setSurname(currentSurname);
		personName.setGivenName(currentGivenName);
		Address address = new Address();
		address.setNumber(currentNumber);
		address.setStreet(currentStreet);
		address.setSuburb(currentSuburb);
		address.setState(currentState);
		address.setPostcode(currentPostcode);
		address.setCountry(currentCountry);
		CreditCard creditCard = new CreditCard();
		creditCard.setType(currentCreditCardType);
		creditCard.setNumber(currentCreditCardNumber);
		creditCard.setSecurityCode(currentCreditCardSecurityCode);
		creditCard.setExpiryMonth(currentCreditCardExpiryMonth);
		creditCard.setExpiryYear(currentCreditCardExpiryYear);
		Customer customer = new Customer();
		customer.setName(personName);
		customer.setEmail(currentEmail);
		customer.setAddress(address);
		customer.setCreditCard(creditCard);
		newPurchase = m_PurchaseManager.create(productsInCart, customer);
		if (newPurchase == null)
		{
			m_Application.addMessage(FacesMessage.SEVERITY_FATAL, "Unable to continue to purchase. Maybe some of the products are out of stock.");
		}
		else
		{
			try
			{
				m_Application.getExternalContext().dispatch("finish.xhtml");
			}
			catch (IOException ex)
			{
				m_Application.getLogger().log(Level.SEVERE, null, ex);
			}
		}
	}
}
